/**
 * @license
 * Copyright 2021 Du Tian Wei
 * SPDX-License-Identifier: Apache-2.0
 */
(function () {
    function makeBlock(workspace, xml) {
        let block = Blockly.Xml.domToBlock(xml, workspace);
        // const blockJson = Blockly.serialization.blocks.save(block);
        return block;
    }
    class ToolboxSearchCategory extends Blockly.ToolboxCategory {
        searching = "";
        constructor(categoryDef, parentToolbox, opt_parent) {
            super(categoryDef, parentToolbox, opt_parent);
        }
        getDiv() {
            return this.createDom_();
        }
        /**
         * Initializes the search field toolbox category.
         *
         * @returns The <div> that will be displayed in the toolbox.
         */
        createDom_() {
            const dom = super.createDom_();
            this.searchField = document.createElement('input');
            this.searchField.type = 'search';
            this.searchField.placeholder = 'Search';
            this.workspace_.RTL
                ? (this.searchField.style.marginRight = '8px')
                : (this.searchField.style.marginLeft = '8px');
            this.searchField.style.paddingLeft = '8px';
            this.searchField.style.paddingRight = '8px';
            this.searchField.addEventListener('keyup', (event) => {
                if (event.key === 'Escape') {
                    this.parentToolbox_.clearSelection();
                    return true;
                }
                this.matchBlocks();
            });
            this.rowContents_?.replaceChildren(this.searchField);
            return dom;
        }  /**
        * Handles a click on this toolbox category.
        *
        * @param e The click event.
        */
        onClick(e) {
            super.onClick(e);
            e.preventDefault();
            e.stopPropagation();
            this.setSelected(this.parentToolbox_.getSelectedItem() === this);
        }

        /**
         * Handles changes in the selection state of this category.
         *
         * @param isSelected Whether or not the category is now selected.
         */
        setSelected(isSelected) {
            super.setSelected(isSelected);
            if (!this.searchField) return;
            if (isSelected) {
                this.searchField.focus();
                this.matchBlocks();
            } else {
                // this.searchField.value = '';
                // this.searchField.blur();
            }
        }

        searchBlock_(workspace, content, result) {
            if ("TOOLBOX_SEARCH_CATEGROY" == content) {
                return;
            } else if (content instanceof Blockly.ToolboxSeparator) {
                return;
            } else if (content instanceof ToolboxSearchCategory) {
                return;
            } else if (Array.isArray(content)) {
                content.forEach(item => {
                    this.searchBlock_(workspace, item, result);
                });
            } else if (typeof (content) === 'string') {
                let categorycallback = workspace.targetWorkspace.getToolboxCategoryCallback(content);
                let xmlList = categorycallback(workspace.targetWorkspace);
                xmlList.forEach(xml => {
                    let type = xml.getAttribute('type');
                    if (type) {
                        type = type.toLowerCase();
                        if (type.indexOf(this.searching) >= 0 || makeBlock(workspace, xml).toString().indexOf(this.searching) >= 0) {
                            result.push(xml);
                        }
                    }
                });
            } else if (content.getToolboxItems) {
                let items = content.getToolboxItems();
                items.forEach(item => {
                    this.searchBlock_(workspace, item, result);
                });
            } else if (content.kind === 'BLOCK') {
                let type = content.type;
                type = type.toLowerCase();
                if (type.indexOf(this.searching) >= 0 || makeBlock(workspace, content.blockxml).toString().toLowerCase().indexOf(this.searching) >= 0) {
                    result.push(content.blockxml);
                }
            } else if (content.getContents) {
                let content1 = content.getContents();
                this.searchBlock_(workspace, content1, result);
            } else {
            }
        }
        searchBlock(workspace) {
            let result = [];
            if (this.searching) {
                let toolbox = workspace.getToolbox();
                var testWorkspace = new Blockly.Workspace();
                testWorkspace.targetWorkspace = workspace;
                this.searchBlock_(testWorkspace, toolbox, result);
                testWorkspace.dispose();
            }
            return result;
        }

        /**
        * Filters the available blocks based on the current query string.
        */
        matchBlocks() {
            const query = this.searchField?.value || '';
            if (query.length == 0) {
                return;
            }
            if (query == this.searching) return;
            this.searching = query;
            this.flyoutItems_ = this.searchBlock(this.parentToolbox_.workspace_);

            if (!this.flyoutItems_.length) {
                this.flyoutItems_.push({
                    kind: 'label',
                    text: OpenBlock.i('未找到任何符合条件的块'),
                });
            }
            this.parentToolbox_.refreshSelection();
        }
    }

    Blockly.registry.register(
        Blockly.registry.Type.TOOLBOX_ITEM,
        "toolbox_search",
        ToolboxSearchCategory,
    );
}());
(function () {
    let searching = "";
    function makeBlock(workspace, xml) {
        let block = Blockly.Xml.domToBlock(xml, workspace);
        return block;
    }
    function searchBlock_(workspace, content, result) {
        if ("TOOLBOX_SEARCH_CATEGROY" === content) {
            return;
        } else if (content instanceof Blockly.ToolboxSeparator) {
            return;
        } else if (Array.isArray(content)) {
            content.forEach(item => {
                searchBlock_(workspace, item, result);
            });
        } else if (typeof (content) === 'string') {
            let categorycallback = workspace.targetWorkspace.getToolboxCategoryCallback(content);
            let xmlList = categorycallback(workspace.targetWorkspace);
            xmlList.forEach(xml => {
                let type = xml.getAttribute('type');
                if (type) {
                    type = type.toLowerCase();
                    if (type.indexOf(searching) >= 0 || makeBlock(workspace, xml).toString().indexOf(searching) >= 0) {
                        result.push(workspace, xml);
                    }
                }
            });
        } else if (content.getToolboxItems) {
            let items = content.getToolboxItems();
            items.forEach(item => {
                searchBlock_(workspace, item, result);
            });
        } else if (content.kind === 'BLOCK') {
            let type = content.type;
            type = type.toLowerCase();
            if (type.indexOf(searching) >= 0 || makeBlock(workspace, content.blockxml).toString().toLowerCase().indexOf(searching) >= 0) {
                result.push(workspace, content.blockxml);
            }
        } else if (content.getContents) {
            let content1 = content.getContents();
            searchBlock_(workspace, content1, result);
        } else {
        }
    }
    function searchBlock(workspace) {
        let result = [];
        if (searching) {
            let toolbox = workspace.getToolbox();
            var testWorkspace = new Blockly.Workspace();
            testWorkspace.targetWorkspace = workspace;
            searchBlock_(testWorkspace, toolbox, result);
            testWorkspace.dispose();
        }
        return result;
    }
    OpenBlock.Blocks.toolbox_search_flyout = function (workspace) {
        var xmlList = [];
        var button = document.createElement('button');
        button.setAttribute('text', '%{BKY_SEARCH}');
        button.setAttribute('callbackKey', 'INPUT_SEARCH_CONTENT');
        xmlList.push(button);

        button = document.createElement('button');
        button.setAttribute('text', '%{BKY_CLEAR}');
        button.setAttribute('callbackKey', 'CLEAR_SEARCH');
        xmlList.push(button);
        if (searching) {
            var button = document.createElement('label');
            button.setAttribute('text', searching);
            button.setAttribute('callbackKey', 'INPUT_SEARCH_CONTENT');
            xmlList.push(button);
            try {
                let result = searchBlock(workspace);
                xmlList = xmlList.concat(result);
            } catch (e) {
                console.error(e);
            }
        }

        return xmlList;
    };
    OpenBlock.Blocks.build_toolbox_search_flyout = function (workspace) {
        workspace.registerButtonCallback("INPUT_SEARCH_CONTENT", () => {
            let p = (OpenBlock.config.uiCallbacks.prompt || window.prompt)(OpenBlock.i('输入搜索关键字'));
            if (p instanceof Promise) {
                p.then(
                    /**
                     * 
                     * @param {string} text 
                     */
                    (text) => {
                        searching = text.toLowerCase();
                        workspace.getToolbox().refreshSelection();
                    });
            } else {
                searching = p;
                workspace.getToolbox().refreshSelection();
            }
        });
        workspace.registerButtonCallback("CLEAR_SEARCH", () => {
            searching = "";
            workspace.getToolbox().refreshSelection();
        });
        workspace.registerToolboxCategoryCallback('TOOLBOX_SEARCH_CATEGROY', OpenBlock.Blocks.toolbox_search_flyout);
    };
    OpenBlock.wsBuildCbs.push(OpenBlock.Blocks.build_toolbox_search_flyout);
})();